#!/usr/bin/perl -w

#=======================================================================
# hf
# File ID: 2a71fba8-5d3b-11df-b18b-90e6ba3022ac
# Formatterer HTML-source med mellomrom eller tabulator.
#
# Laget av Øyvind A. Holm <sunny@sunbase.org>
# Lisens: GNU General Public License versjon 2 eller nyere
#
# FIXME: Hvis start+end-elementer står på samme linje, blir ikke 
# innrykket rett. En eller annen rekursiv sjekk på linjene må kanskje 
# gjøres. Foreløpig får man sette dem på hver sin linje.
#=======================================================================

use strict;
use Getopt::Std;

my $STD_SPACE = 2;

our ($opt_a, $opt_E, $opt_h, $opt_H, $opt_i, $opt_s, $opt_t, $opt_w) =
    (     0,      0,      0,      0,      0,      0,      0,      0);
our $opt_n = $STD_SPACE;

getopts('aEhHi:n:stw');

my $is_pre = 0;
my $prog_name = $0;
$prog_name =~ s#.*/(.+?)$#$1#;

print_help() if ($main::opt_h);

$| = 1;

my $Tabs = "";
my $Spaces = " " x $opt_n;
$opt_t || ($opt_a = 1);
my $tab_indent = $main::opt_i;
my $orig_line = "";
my @Elements = (
    "applet", "blockquote", "body", "caption", "center", "colgroup", 
    "div", "dl", "form", "frameset", "html", "map", "noframes", 
    "noscript", "ol", "select", "table", "tbody", "td", "tfoot", "th", 
    "thead", "tr", "ul"
);
my $pre_exp="head|pre|script|rdf:RDF";

$tab_indent = 0 if ($tab_indent <= 0);

for (; $tab_indent; $tab_indent--) {
    $Tabs .= "\t";
}

my $line_exp = $main::opt_a ? '^\s+(.*)' : '^\t+(.*)';
my $header_indent = "";

LINE: while (<>) {
    # {{{
    chomp;
    my $Line = $_;
    my $Element = "";
    my $f = "";
    my $out_line;

    # Ignorer linjer som begynner med % hvis -s er spesifisert
    $main::opt_s && ($Line =~ /^%/) && (print($Line), next LINE);

    unless ($is_pre) {
        # $Line =~ $main::opt_s ? s/^\s+(.*?)\s+$/$1/ : s/^\t+(.*)/$1/;
        $Line =~ s/$line_exp/$1/;
        if ($main::opt_H && $Line =~ /<h([1-6]).*?>/i) {
            $header_indent = "\t" x ($1-1);
        }
        ($Line =~ m!</body>!i) && ($header_indent = "");
        unless ($opt_E) {
            for $f (@Elements) {
                if ($Line =~ m!</($f)([ >])!i) {
                    # Slutt-tag ble funnet {{{
                    $Element = $1;
                    $tab_indent--;
                    $Tabs =~ s/\t$//;
                    # $Line =~ s/($Element)/sprintf("\n%s%s", $Tabs, $1)/gei;
                    # }}}
                }
            }
        }
        $out_line = "$header_indent$Tabs$Line";

        # Fjern alle whitespace på slutten
        $opt_w && $out_line =~ s/[ \t]+$//g;

        # Hvis -t i̲k̲k̲e̲ er spesifisert, vil vi ikke ha TAB’er og de skal 
        # dermed erstattes med space.
        $opt_t || ($out_line =~ s/\t/$Spaces/g);

        # Linjer som bare har whitespace tømmer vi. Det er mest 
        # sannsynlig et resultat av indentinga.
        $out_line =~ s/^[ \t]+$//;

        print("$out_line\n");
        unless ($opt_E) {
            for $f (@Elements) {
                if ($Line =~ m!<($f)([ >])!i) {
                    # Start-tag ble funnet {{{
                    $Element = $1;
                    $tab_indent++;
                    $Tabs .= "\t";
                    # $Line =~ s/($Element)/sprintf("\n%s%s", $Tabs, $1)/gei;
                    # }}}
                }
            }
        }
    } else {
        print("$_\n");
    }
    $is_pre = 1 if ($Line =~ /<($pre_exp)\b.*>/i);
    $is_pre = 0 if ($Line =~ m!</($pre_exp)>!i);
    # }}}
}

sub print_help {
    # {{{
    print <<END;

HTML formatter
Syntax: $0 [valg] [filer [...]]

Options:
  -a    Fjern space i begynnelsen av linja også før indenting. Funker 
        bare sammen med «-t»-parameteret. Utenom det er den bestandig 
        på, det vil si at alle spacer skvises.
  -h    Vis denne hjelpen
  -H    Legg til en TAB for hver <h1>, <h2>, <h3> osv for å lettere se 
        strukturen i dokumentet.
  -i n  Start med n TAB’er som indent
  -n x  Bruk x spacer som indent. Standard verdi er $STD_SPACE. 
        Ignoreres hvis «-t»-parameteret brukes.
  -w    Fjern whitespace på slutten av linjene
  -s    Dropp linjer som her en % i starten. Det er datafilene på 
        www.sunbase.org som er sånn.
  -t    Sett inn TAB istedenfor space, akkurat som i gamle dager.

END
    exit(0);
    # }}}
}

=pod

=head1 LICENCE

This program is free software; you can redistribute it and/or modify it 
under the terms of the GNU General Public License as published by the 
Free Software Foundation; either version 2 of the License, or (at your 
option) any later version.

This program is distributed in the hope that it will be useful, but 
WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along 
with this program; if not, write to the Free Software Foundation, Inc., 
59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

=cut

# vim: set ft=perl sw=4 ts=4 sts=4 et fenc=utf8 :
# End of file hf
